<?php
require_once("Token.php");
require_once("Lex.php");
require_once("CompilerPHP.php");
require_once("PreProcessor.php");

/*$test = function test1()
{
	function test2()
	{
		echo "test ";
	}
	test2();
};
$test();*/

$token = new TokenMngr(array( 
	"var",
	"mem_var",
	"create var",
	"var_str",
	"number",
	"string",
	"instruction",
	"list_instruction",
	"function",
	"function_anonymous",
	"function_str",
	"list_var",
	"var_type",
	",",
	";",
	"=",
	"+=",
	"-=",
	"*=",
	"/=",
	"?",
	":",
	"&&",
	"||",
	"==",
	"!=",
	"<",
	"<=",
	">=",
	">",
	"+",
	"-",
	"prefix -",
	"*",
	"/",
	"--",
	"++",
	"!",
	"(",
	")",
	"[",
	"]",
	"{",
	"}",
	));

$numberType = new VarType();
$numberType->name = "Number";
$numberADD = new MethodParam();
$numberADD->name = 'operator+';
$numberADD->arguments[] = $numberType;
$numberADD->returnType = $numberType;
$numberType->methods[] = $numberADD;
$numberSUB = new MethodParam();
$numberSUB->name = 'operator-';
$numberSUB->arguments[] = $numberType;
$numberSUB->returnType = $numberType;
$numberType->methods[] = $numberSUB;

$token->listVarType[] = $numberType;

$token->addTokenState("right", array("=","+=","-=","*=","/="));
$token->addTokenState("left", array("?",":"));
$token->addTokenState("left", array("&&","||"));
$token->addTokenState("left", array("==","!="));
$token->addTokenState("left", array("<","<=",">=",">"));
$token->addTokenState("left", array("+","-"));
$token->addTokenState("left", array("*","/"));
$token->addTokenState("left", array("--","++","!", "prefix -"));
//$token->addTokenState("right", array("^"));

$parser = new Parser($token);
$parser->addRule(new RegexRule($token->getId("number"), "/[0-9]+/"));
$parser->addRule(new RegexRule($token->getId("string"), "/[a-zA-Z][a-zA-Z0-9_]*/"));
$parser->addRule(new TextRule($token->getId("var_str"), "var"));
$parser->addRule(new TextRule($token->getId("function_str"), "function"));
$parser->addRule(new TextRule($token->getId("="), "="));
$parser->addRule(new TextRule($token->getId("+="), "+="));
$parser->addRule(new TextRule($token->getId("-="), "-="));
$parser->addRule(new TextRule($token->getId("*="), "*="));
$parser->addRule(new TextRule($token->getId("/="), "/="));
$parser->addRule(new TextRule($token->getId("?"), "?"));
$parser->addRule(new TextRule($token->getId(":"), ":"));
$parser->addRule(new TextRule($token->getId("&&"), "&&"));
$parser->addRule(new TextRule($token->getId("||"), "||"));
$parser->addRule(new TextRule($token->getId("=="), "=="));
$parser->addRule(new TextRule($token->getId("!="), "!="));
$parser->addRule(new TextRule($token->getId("<"), "<"));
$parser->addRule(new TextRule($token->getId("<="), "<="));
$parser->addRule(new TextRule($token->getId(">="), ">="));
$parser->addRule(new TextRule($token->getId(">"), ">"));
$parser->addRule(new TextRule($token->getId("+"), "+"));
$parser->addRule(new TextRule($token->getId("-"), "-"));
$parser->addRule(new TextRule($token->getId("*"), "*"));
$parser->addRule(new TextRule($token->getId("/"), "/"));
$parser->addRule(new TextRule($token->getId("--"), "--"));
$parser->addRule(new TextRule($token->getId("++"), "++"));
$parser->addRule(new TextRule($token->getId("!"), "!"));
$parser->addRule(new TextRule($token->getId("prefix -"), "-"));
$parser->addRule(new TextRule($token->getId("("), "("));
$parser->addRule(new TextRule($token->getId(")"), ")"));
$parser->addRule(new TextRule($token->getId("["), "["));
$parser->addRule(new TextRule($token->getId("]"), "]"));
$parser->addRule(new TextRule($token->getId("{"), "{"));
$parser->addRule(new TextRule($token->getId("}"), "}"));
$parser->addRule(new TextRule($token->getId(";"), ";"));
$parser->addRule(new TextRule($token->getId(","), ","));
//$parser->addRule(new TextRule($token->getId("^"), "^"));
$varRule = new CombineRule($token->getId("var"));
$varRule->addArrayToken($token->getId(array("function_anonymous")));
$varRule->addArrayToken($token->getId(array("number")));
$varRule->addArrayToken($token->getId(array("prefix -","var")));
$varRule->addArrayToken($token->getId(array("++","mem_var")));
$varRule->addArrayToken($token->getId(array("--","mem_var")));
$varRule->addArrayToken($token->getId(array("!","var")));
$varRule->addArrayToken($token->getId(array("mem_var","++")));
$varRule->addArrayToken($token->getId(array("mem_var","--")));
$varRule->addArrayToken($token->getId(array("mem_var")));
$varRule->addArrayToken($token->getId(array("(","var", ")")));
$varRule->addArrayToken($token->getId(array("var","==","var")));
$varRule->addArrayToken($token->getId(array("var","!=","var")));
$varRule->addArrayToken($token->getId(array("var","+","var")));
$varRule->addArrayToken($token->getId(array("var","-","var")));
$varRule->addArrayToken($token->getId(array("var","*","var")));
$varRule->addArrayToken($token->getId(array("var","/","var")));
$varRule->addArrayToken($token->getId(array("var","&&","var")));
$varRule->addArrayToken($token->getId(array("var","||","var")));
$varRule->addArrayToken($token->getId(array("var","?","var",":","var")));
$varRule->addArrayToken($token->getId(array("var","<","var")));
$varRule->addArrayToken($token->getId(array("var","<=","var")));
$varRule->addArrayToken($token->getId(array("var",">","var")));
$varRule->addArrayToken($token->getId(array("var",">=","var")));
$parser->addRule($varRule);
$memVarRule = new CombineRule($token->getId("mem_var"));
$memVarRule->addArrayToken($token->getId(array("string")));
$memVarRule->addArrayToken($token->getId(array("(", "mem_var", ")")));
$memVarRule->addArrayToken($token->getId(array("mem_var","=","var")));
$memVarRule->addArrayToken($token->getId(array("mem_var","+=","var")));
$memVarRule->addArrayToken($token->getId(array("mem_var","-=","var")));
$memVarRule->addArrayToken($token->getId(array("mem_var","*=","var")));
$memVarRule->addArrayToken($token->getId(array("mem_var","/=","var")));
$parser->addRule($memVarRule);
$varTypeRule = new CombineRule($token->getId("var_type"));
$varTypeRule->addArrayToken($token->getId(array("string")));
$parser->addRule($varTypeRule);
$createVarRule = new CombineRule($token->getId("create var"));
$createVarRule->addArrayToken($token->getId(array("var_str","string",":","var_type")));
$createVarRule->addArrayToken($token->getId(array("var_str","string")));
$parser->addRule($createVarRule);
$instructionRule = new CombineRule($token->getId("instruction"));
$instructionRule->addArrayToken($token->getId(array("create var",";")));
$instructionRule->addArrayToken($token->getId(array("create var","=","var",";")));
$instructionRule->addArrayToken($token->getId(array("create var","+=","var",";")));
$instructionRule->addArrayToken($token->getId(array("create var","-=","var",";")));
$instructionRule->addArrayToken($token->getId(array("create var","*=","var",";")));
$instructionRule->addArrayToken($token->getId(array("create var","/=","var",";")));
$instructionRule->addArrayToken($token->getId(array("var",";")));
$instructionRule->addArrayToken($token->getId(array("function")));
$parser->addRule($instructionRule);
$listInstructionRule = new CombineRule($token->getId("list_instruction"));
$listInstructionRule->addArrayToken($token->getId(array("instruction","list_instruction")));
$listInstructionRule->addArrayToken($token->getId(array("instruction")));
$parser->addRule($listInstructionRule);
$listVarRule = new CombineRule($token->getId("list_var"));
$listVarRule->addArrayToken($token->getId(array("list_var",",","list_var")));
$listVarRule->addArrayToken($token->getId(array("string", ":", "var_type")));
$listVarRule->addArrayToken($token->getId(array("string")));
$parser->addRule($listVarRule);
$functionRule = new CombineRule($token->getId("function"));
$functionRule->addArrayToken($token->getId(array("function_str","string","(","list_var",")",":","var_type","{","list_instruction","}")));
$functionRule->addArrayToken($token->getId(array("function_str","string","(","list_var",")","{","list_instruction","}")));
$parser->addRule($functionRule);
$functionAnonymousRule = new CombineRule($token->getId("function_anonymous"));
$functionAnonymousRule->addArrayToken($token->getId(array("function_str","(","list_var",")",":","var_type","{","list_instruction","}")));
$functionAnonymousRule->addArrayToken($token->getId(array("function_str","(","list_var",")","{","list_instruction","}")));
$parser->addRule($functionAnonymousRule);
//echo $parser->parse("function test(a : Int) {var a : Int = 5;}","list_instruction")->toString($parser->tokenMngr);
$compiler = new CompilerPHP($token);
$compiler->compile($parser->parse("var a : Int = 5+2*3; a -= a+3;","list_instruction"));

$preprocessor = new PreProcessor();
echo $preprocessor->parse(new DataReader("test1 #define salut System.out.println(\"salut\"); \n salut #if saluut\n salut #else\n #define salut printf(\"salut\"); \n #endif salut "));
var_dump($preprocessor->defines);
?>